﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CustomUIControls;
using ICases;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace FalsePositiveWindows
{
    public partial class Form1 : Form
    {
        public List<Case> cases = new List<Case>();
        public List<Point> lastPoints = new List<Point>();

        private NotifyIcon trayIcon;

        private ContextMenu trayMenu;


        protected override void OnLoad(EventArgs e)
        {

            Visible = false; // Hide form window.

            ShowInTaskbar = false; // Remove from taskbar.

            taskbar = new Taskbar();

            base.OnLoad(e);

        }


        Taskbar taskbar;
        private void OnExit(object sender, EventArgs e)
        {

            Application.Exit();

        }


        private void OnClearLog(object sender, EventArgs e)
        {

            if (System.IO.File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\mouse.data.txt"))
                if (MessageBox.Show("Tem certeza que deseja apagar o log?", "Apagar log", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                    System.IO.File.Delete(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\mouse.data.txt");

        }

        private void OnLog(object sender, EventArgs e)
        {

            if (System.IO.File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\mouse.data.txt"))
                Process.Start(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\mouse.data.txt");
            else
                MessageBox.Show("Ainda não foi registrado nenhum log.");

        }

        int iCases = 0;
        public Form1()
        {
            InitializeComponent();

            trayMenu = new ContextMenu();

            trayMenu.MenuItems.Add("Sair", OnExit);
            trayMenu.MenuItems.Add("Ver Log", OnLog);
            trayMenu.MenuItems.Add("Limpar Log", OnClearLog);




            // Create a tray icon. In this example we use a

            // standard system icon for simplicity, but you

            // can of course use your own custom icon too.

            trayIcon = new NotifyIcon();

            trayIcon.Text = "MouseLog - " + Application.ProductVersion;

            trayIcon.Icon = new Icon(SystemIcons.Application, 40, 40);



            // Add menu to tray icon and show it.

            trayIcon.ContextMenu = trayMenu;

            trayIcon.Visible = true;

        }
      

        private void timer1_Tick(object sender, EventArgs e)
        {
            Point lastPoint = Control.MousePosition;

            lastPoints.Add(lastPoint);

            if 
                (
                (taskbar.Position == TaskbarPosition.Left && lastPoint.X == 0)
                ||
            (taskbar.Position == TaskbarPosition.Right && lastPoint.X == Screen.PrimaryScreen.Bounds.Width - 1)
                ||
            (taskbar.Position == TaskbarPosition.Top && lastPoint.Y == 0)
            ||
            (taskbar.Position == TaskbarPosition.Bottom && lastPoint.Y == Screen.PrimaryScreen.Bounds.Height-1))
            {
                if (lastCount.Subtract(DateTime.Now).TotalMilliseconds > -500)
                    return;

                if (iCases == 9)
                    return;

                Case case1 = new Case(iCases++);
                case1.Close += new EventHandler(case1_Close);
                case1.onPause += new EventHandler(case1_onPause);
                if (lastPoints.Count > 9)
                {
                    lastPoints.CopyTo(lastPoints.Count - 10, case1.Lista, 0, 10);

                    cases.Add(case1);
                    lastPoints.RemoveRange(0, lastPoints.Count - 10);
                }
                else
                {
                    lastPoints.Clear();
                }
                lastCount = DateTime.Now;

                case1.taskbarNotifier.Show(case1);
            }

        }

        DateTime lastCount = DateTime.Now;
        void case1_onPause(object sender, EventArgs e)
        {
            foreach (Case c in cases)
            {
                c.Pause();
            }
        }

        void case1_Close(object sender, EventArgs e)
        {
            iCases--;
        }

        //IntPtr desktop = IntPtr.Zero;
        //void taskbarNotifier_MouseMove(object sender, EventArgs e)
        //{
        //    if(desktop == IntPtr.Zero
        //    desktop = GetDC(IntPtr.Zero);

        //    using (Graphics g = Graphics.FromHdc(desktop))
        //    {
        //        g.FillRectangle(Brushes.Red, 0, 0, 100, 100);
        //    }

        //}


        //[DllImport("User32.dll")]
        //static extern IntPtr GetDC(IntPtr hwnd);

        //[DllImport("User32.dll")]
        //static extern void ReleaseDC(IntPtr dc);
    }

    
    public class Case : ICase
    {

        public event EventHandler Close = null;
        public event EventHandler onPause = null;

        int _i = -1;
        public Case(int i)
        {
            _i = i;
            Resolvido = false;
            Abriu = false;
            DeveriaAbrir = false;
            Lista = new Point[10];

            taskbarNotifier = new TaskbarNotifier(i);
            taskbarNotifier.Close += new EventHandler(taskbarNotifier_Close);
            taskbarNotifier.MouseLeave += new EventHandler(taskbarNotifier_MouseEnter);
            taskbarNotifier.MouseEnter += new EventHandler(taskbarNotifier_MouseEnter);
            //taskbarNotifier.TitleRectangle = new Rectangle(40, 9, 70, 25);
            //taskbarNotifier.ContentRectangle = new Rectangle(8, 41, 133, 68);
            //taskbarNotifier.TitleClick += new EventHandler("Teste");
            //taskbarNotifier.ContentClick += new EventHandler(ContentClick);
            //taskbarNotifier.CloseClick += new EventHandler(CloseClick);

        }

        void taskbarNotifier_MouseEnter(object sender, EventArgs e)
        {
            if (this.onPause != null)
                this.onPause(null, null);
        }

        void taskbarNotifier_Close(object sender, EventArgs e)
        {
            if (this.Close != null)
                this.Close(_i, null);
        }

        public bool Resolvido { get; set; }
        public Point[] Lista { get; set; }
        public bool Abriu { get; set; }
        public bool DeveriaAbrir { get; set; }
        public TaskbarNotifier taskbarNotifier { get; set; }

        public void Pause()
        {
            if (taskbarNotifier.timer.Enabled)
                this.taskbarNotifier.timer.Stop();
            else
                this.taskbarNotifier.timer.Start();
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendFormat("{0};{1};{2};{3};",
                DateTime.Now.Ticks.ToString(),
                Screen.GetWorkingArea(Lista[0]).ToString(),
                Abriu,
                DeveriaAbrir);

            foreach (Point p in Lista)
            {
                sb.Append(p.ToString() + ";");
            }
            sb.AppendLine();

            return sb.ToString();
        }
    }

    public enum TaskbarPosition
    {
        Unknown = -1,
        Left,
        Top,
        Right,
        Bottom,
    }


    public sealed class Taskbar
    {
        private const string ClassName = "Shell_TrayWnd";

        public Rectangle Bounds
        {
            get;
            private set;
        }
        public TaskbarPosition Position
        {
            get;
            private set;
        }
        public Point Location
        {
            get
            {
                return this.Bounds.Location;
            }
        }
        public Size Size
        {
            get
            {
                return this.Bounds.Size;
            }
        }
        //Always returns false under Windows 7
        public bool AlwaysOnTop
        {
            get;
            private set;
        }
        public bool AutoHide
        {
            get;
            private set;
        }

        public Taskbar()
        {
            IntPtr taskbarHandle = User32.FindWindow(Taskbar.ClassName, null);

            APPBARDATA data = new APPBARDATA();
            data.cbSize = (uint)Marshal.SizeOf(typeof(APPBARDATA));
            data.hWnd = taskbarHandle;
            IntPtr result = Shell32.SHAppBarMessage(ABM.GetTaskbarPos, ref data);
            if (result == IntPtr.Zero)
                throw new InvalidOperationException();

            this.Position = (TaskbarPosition)data.uEdge;
            this.Bounds = Rectangle.FromLTRB(data.rc.left, data.rc.top, data.rc.right, data.rc.bottom);

            data.cbSize = (uint)Marshal.SizeOf(typeof(APPBARDATA));
            result = Shell32.SHAppBarMessage(ABM.GetState, ref data);
            int state = result.ToInt32();
            this.AlwaysOnTop = (state & ABS.AlwaysOnTop) == ABS.AlwaysOnTop;
            this.AutoHide = (state & ABS.Autohide) == ABS.Autohide;
        }
    }

    public enum ABM : uint
    {
        New = 0x00000000,
        Remove = 0x00000001,
        QueryPos = 0x00000002,
        SetPos = 0x00000003,
        GetState = 0x00000004,
        GetTaskbarPos = 0x00000005,
        Activate = 0x00000006,
        GetAutoHideBar = 0x00000007,
        SetAutoHideBar = 0x00000008,
        WindowPosChanged = 0x00000009,
        SetState = 0x0000000A,
    }

    public enum ABE : uint
    {
        Left = 0,
        Top = 1,
        Right = 2,
        Bottom = 3
    }

    public static class ABS
    {
        public const int Autohide = 0x0000001;
        public const int AlwaysOnTop = 0x0000002;
    }

    public static class Shell32
    {
        [DllImport("shell32.dll", SetLastError = true)]
        public static extern IntPtr SHAppBarMessage(ABM dwMessage, [In] ref APPBARDATA pData);
    }

    public static class User32
    {
        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct APPBARDATA
    {
        public uint cbSize;
        public IntPtr hWnd;
        public uint uCallbackMessage;
        public ABE uEdge;
        public RECT rc;
        public int lParam;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }
}
